"""
Case Type   : 共享存储-系统内部工具-dsscmd
Case Name   : dsscmd工具显示带有可选参数的文件/目录的磁盘使用情况
Create At   : 2023/4/13
Owner       : opentestcase019
Description :
    1.显示带有可选参数的文件/目录的磁盘使用情况，指定-p path参数为有效值
    2.显示带有可选参数的文件/目录的磁盘使用情况，指定-p path参数为不存在的路径
    3.显示带有可选参数的文件/目录的磁盘使用情况，指定-p path参数为包含特殊字符的路径
    4.显示带有可选参数的文件/目录的磁盘使用情况，指定-f format参数为有效值
    5.显示带有可选参数的文件/目录的磁盘使用情况，指定-f format参数为取值范围之外的值
    6.显示带有可选参数的文件/目录的磁盘使用情况，指定-U UDS:socket_domain参数为正常值
    7.显示带有可选参数的文件/目录的磁盘使用情况，指定指定错误的-U UDS:socket_domain参数和权限不足的socket_domain
    8.在集群停止的情况下执行
    9.在dss关闭的情况下执行
Expect      :
    1.显示成功
    2.合理报错
    3.合理报错
    4.显示成功
    5.合理报错
    6.显示成功
    7.合理报错Failed to get uds connection.
    8.合理报错
    9.合理报错
History     :
"""
import os
import re
import time
import unittest
from yat.test import Node
from yat.test import macro
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant


class ShareStorageTool(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        self.logger.info(f"-----{os.path.basename(__file__)} start-----")
        self.primary_node = Node('PrimaryDbUser')
        self.primary_sh = CommonSH('PrimaryDbUser')
        self.common = Common()
        self.constant = Constant()

    def test_sharestorage_tool(self):
        step1 = "-----step1:显示带有可选参数的文件/目录的磁盘使用情况，" \
                "指定-p path参数为有效值;expect:显示成功-----"
        self.logger.info(step1)
        self.logger.info("-----获取卷组名-----")
        execute_cmd = f"source {macro.DB_ENV_PATH};dsscmd lsvg"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn("Succeed to display lsvg info.", execute_msg, "获取卷组名失败")
        vgname = execute_msg.splitlines()[1].split()[0].strip()
        self.logger.info(vgname)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd du -p +{vgname} -f K;dsscmd du -p +{vgname}/base -f M"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        expect_1 = f"[0-9]*K.*{vgname}.*\\n"
        search_res_1 = re.search(expect_1, execute_msg, re.S)
        self.assertIsNotNone(search_res_1, '执行失败' + step1)
        expect_2 = f"[0-9]*M.*{vgname}.*\\n"
        search_res_2 = re.search(expect_2, execute_msg, re.S)
        self.assertIsNotNone(search_res_2, '执行失败' + step1)

        step2 = "-----step2:显示带有可选参数的文件/目录的磁盘使用情况，" \
                "指定-p path参数为不存在的路径;expect:合理报错-----"
        self.logger.info(step2)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd du -p +{vgname}_not -f M"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"Failed to traverse path +{vgname}_not.\n detail "
                      f"reason [2040] : Failed to find volume group "
                      f"{vgname}_not, please check vg config file",
                      execute_msg, "执行失败" + step2)

        step3 = "-----step3:显示带有可选参数的文件/目录的磁盘使用情况，" \
                "指定-p path参数为包含特殊字符的路径;expect:合理报错-----"
        self.logger.info(step3)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd du -p +{vgname}@ -f s;dsscmd du -p +{vgname}# -f a"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"cmd du error:2193 Path {vgname}@ decode error , "
                      f"path should be [0~9,a~z,A~Z,-,_,/,.].",
                      execute_msg, "执行失败" + step3)
        self.assertIn(f"cmd du error:2193 Path {vgname}# decode error , "
                      f"path should be [0~9,a~z,A~Z,-,_,/,.].",
                      execute_msg, "执行失败" + step3)

        step4 = "-----step4:显示带有可选参数的文件/目录的磁盘使用情况，" \
                "指定-f format参数为有效值;expect:显示成功-----"
        self.logger.info(step4)
        cmd_list = ["B", "G", "T", "s", "a", "S"]
        for cmd in cmd_list:
            execute_cmd = f"source {macro.DB_ENV_PATH};" \
                f"dsscmd du -p +{vgname} -f {cmd}"
            self.logger.info(execute_cmd)
            execute_msg = self.common.get_sh_result(self.primary_node,
                                                    execute_cmd)
            if cmd in cmd_list[0:2]:
                expect = f"[0-9]*{cmd}.*{vgname}.*\\n"
                search_res = re.search(expect, execute_msg, re.S)
                self.assertIsNotNone(search_res, '执行失败' + step4)
            else:
                expect = f"[0-9]*.*{vgname}"
                search_res = re.search(expect, execute_msg, re.S)
                self.assertIsNotNone(search_res, '执行失败' + step4)

        step5 = "-----step5:显示带有可选参数的文件/目录的磁盘使用情况，" \
                "指定-f format参数为取值范围之外的值;expect:合理报错-----"
        self.logger.info(step5)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd du -p +{vgname} -f Byte;" \
            f"dsscmd du -p +{vgname} -f 111;" \
            f"dsscmd du -p +{vgname} -f %$*"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        exp = "The name's letter of du_format should be [BKMGT|sa|S]."
        self.assertEquals(3, execute_msg.count(exp), "执行失败" + step5)

        step6 = "-----step6:显示带有可选参数的文件/目录的磁盘使用情况，" \
                "指定-U UDS:socket_domain参数为正常值;expect:显示成功-----"
        self.logger.info(step6)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd du -p +{vgname} -f B -U {macro.UDS_PATH}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        expect = f".*{vgname}.*\\n"
        search_res = re.search(expect, execute_msg, re.S)
        self.assertIsNotNone(search_res, '执行失败' + step6)

        step7 = "-----step7:显示带有可选参数的文件/目录的磁盘使用情况，" \
                "指定错误的-U UDS:socket_domain参数和权限不足的socket_domain;" \
                "expect:合理报错Failed to get uds connection.-----"
        self.logger.info(step7)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd du -p +{vgname} -f M -U {macro.UDS_PATH}.cfg"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step6)
        execute_cmd = f"chmod 000 {macro.UDS_PATH[4::]};" \
            f"source {macro.DB_ENV_PATH};" \
            f"dsscmd du -p +{vgname} -f s -U {macro.UDS_PATH};" \
            f"chmod 600 {macro.UDS_PATH[4::]};"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step6)

        step8 = "-----step8:在集群停止的情况下执行;expect:读取成功-----"
        self.logger.info(step8)
        stop_msg = self.primary_sh.exec_cm_ctl(mode='stop')
        self.logger.info(stop_msg)
        self.assertIn(self.constant.cm_stop_success_msg,
                      stop_msg, '执行失败' + step8)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd du -p +{vgname} -f K;dsscmd du -p +{vgname}/base -f M"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step8)
        start_msg = self.primary_sh.exec_cm_ctl(mode='start')
        self.logger.info(start_msg)
        self.assertIn(self.constant.cm_start_success_msg,
                      start_msg, '启动集群失败')
        time.sleep(30)
        status = self.primary_sh.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败')

        step9 = "-----step9:在dss关闭的情况下执行;expect:合理报错-----"
        self.logger.info(step9)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd stopdss;" \
            f"sleep 2;" \
            f"dsscmd du -p +{vgname} -f K;" \
            f"dsscmd du -p +{vgname}/base -f M"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"Succeed to stop server.", execute_msg, "执行失败" + step9)
        self.assertEquals(2, execute_msg.count(
            self.constant.failed_to_get_uds_connection), "执行失败" + step9)

    def tearDown(self):
        self.logger.info("-----恢复环境-----")
        status = self.primary_sh.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        if "cluster_state   : Normal" not in status:
            start_msg = self.primary_sh.exec_cm_ctl(mode='start')
            self.logger.info(start_msg)
        time.sleep(30)
        status = self.primary_sh.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        self.assertIn('cluster_state   : Normal', status, '恢复环境失败')
        self.logger.info(f"-----{os.path.basename(__file__)} end-----")
